﻿#region File Description

//-----------------------------------------------------------------------------
// IDatabase.cs
//
// Author: ITU Team3 (2012)
//-----------------------------------------------------------------------------

#endregion File Description

#region Using Statements

using System;
using System.Collections.Generic;

#endregion Using Statements

namespace rentit03_server.Database
{
    interface IDatabase
    {
        /// <summary>
        /// Authenticate the users email and password.
        /// </summary>
        /// <param name="email">The email to authenticate</param>
        /// <param name="password">The password to authenticate</param>
        /// <returns>True if successfully authenticated the user, otherwise false</returns>
        User AuthenticateUser(string email, string password);

        /// <summary>
        /// Checks if the specified username exists in the database
        /// </summary>
        /// <param name="email">The username</param>
        /// <returns>True if the username exists in the database</returns>
        bool UsernameExists(string email);

        /// <summary>
        /// Create a new user in the database
        /// </summary>
        /// <param name="user">User object</param>
        /// <returns>True if successfully created</returns>
        int CreateUser(User user);

        /// <summary>
        /// Loads a specific user from the database
        /// </summary>
        /// <param name="uId">User ID</param>
        /// <returns>User object</returns>
        User ReadUser(int uId);

        /// <summary>
        /// Edits a specific user in the database
        /// </summary>
        /// <param name="user">Edited user object</param>
        /// <param name="uId">User id</param>
        /// <returns>True if successfully edited</returns>
        bool EditUser(User user, int uId);

        /// <summary>
        /// Deletes a specific user in the database
        /// </summary>
        /// <param name="uId">User id</param>
        /// <returns>True if successfully deleted</returns>
        bool DeleteUser(int uId);

        /// <summary>
        /// Get a list of users matching the search parameters
        /// </summary>
        /// <param name="condition">The user search parameter object</param>
        /// <returns>A list of user objects</returns>
        List<User> OverviewUser(UserSearchParameter condition);

        /// <summary>
        /// Adds an existing role to a user
        /// </summary>
        /// <param name="rId">The role id</param>
        /// <param name="uId">The user id</param>
        /// <returns></returns>
        bool AddRoleToUser(int rId, int uId);

        /// <summary>
        /// Change the password of a user
        /// </summary>
        /// <param name="uId">The id of the user</param>
        /// <param name="newPassword">The new password</param>
        /// <returns>True if successfully changed the password</returns>
        bool ChangePassword(int uId, string newPassword);

        /// <summary>
        /// Edits the credits of a user
        /// </summary>
        /// <param name="uId">The user id</param>
        /// <param name="amount">The amount to add/subtract</param>
        /// <returns></returns>
        bool EditCredits(int uId, int amount);

        /// <summary>
        /// Reads the credits of a user
        /// </summary>
        /// <param name="uId">The user id</param>
        /// <returns>The id of the user</returns>
        int ReadCredits(int uId);

        /// <summary>
        /// Creates a permission
        /// </summary>
        /// <param name="permission">The RentitPermisssion to create</param>
        /// <returns>The id of the permission</returns>
        int CreatePermission(RentitPermission permission);

        /// <summary>
        /// Reads a specific permission
        /// </summary>
        /// <param name="pId">The id of the permission</param>
        /// <returns>A permission object</returns>
        Permission ReadPermission(int pId);

        /// <summary>
        /// Edits a permission
        /// </summary>
        /// <param name="permission">The edited permission</param>
        /// <param name="pId">The permission id</param>
        /// <returns>True if successfully edited</returns>
        bool EditPermission(Permission permission, int pId);

        /// <summary>
        /// Deletes a specific permission
        /// </summary>
        /// <param name="pId">The id of the permission</param>
        /// <returns>True if successfully deleted</returns>
        bool DeletePermission(int pId);

        /// <summary>
        /// Get a list of all the permissions
        /// </summary>
        /// <returns>A list of permission objects</returns>
        List<Permission> OverviewPermission();

        /// <summary>
        /// Get a list of all versions of a media
        /// </summary>
        /// <param name="mId">The id of the media</param>
        /// <returns>A list of version objects</returns>
        List<Version> OverviewVersions(int mId);

        /// <summary>
        /// Read a specific version
        /// </summary>
        /// <param name="vId">The id of the version</param>
        /// <returns>A version object</returns>
        Version ReadVersion(int vId);

        /// <summary>
        /// Create a role
        /// </summary>
        /// <param name="role">The RentitRole object to create</param>
        /// <returns>The id of the role</returns>
        int CreateRole(RentitRole role);

        /// <summary>
        /// Read a specific role
        /// </summary>
        /// <param name="name">The name of the role</param>
        /// <returns>The role object</returns>
        Role ReadRole(string name);

        /// <summary>
        /// Edit a specific role
        /// </summary>
        /// <param name="role">The edited role object</param>
        /// <param name="rId">The id of the role to edit</param>
        /// <returns>True if successfully edited</returns>
        bool EditRole(Role role, int rId);

        /// <summary>
        /// Get a list of all roles
        /// </summary>
        /// <returns>A list of role objects</returns>
        List<Role> OverviewRole();

        /// <summary>
        /// Purchase a media
        /// </summary>
        /// <param name="uId">The id of the user</param>
        /// <param name="vId">The id of the version of the media</param>
        /// <param name="cost">The version price of the media </param>
        /// <returns>True if successfully purchased</returns>
        bool Purchase(int uId, int vId, int cost);

        /// <summary>
        /// Get a list of a users purchases
        /// </summary>
        /// <param name="uId">The id of the user</param>
        /// <returns>A list of purchases made by the user</returns>
        List<Purchase> OverviewPurchases(int uId);

        /// <summary>
        /// Create a media in the database
        /// </summary>
        /// <param name="media">¨The media object to create</param>
        /// <returns>The media id</returns>
        int CreateMedia(Media media);

        /// <summary>
        /// Loads a specific media from the database
        /// </summary>
        /// <param name="mId">The id of the media to create</param>
        /// <returns>A media object</returns>
        Media ReadMedia(int mId);

        /// <summary>
        /// Read a specific media
        /// </summary>
        /// <param name="mTitle">The title of the media</param>
        /// <param name="mYear">The year of the media</param>
        /// <returns>A media object</returns>
        Media ReadMedia(string mTitle, int mYear);

        /// <summary>
        /// Edit a specific media
        /// </summary>
        /// <param name="movie">The edited media object</param>
        /// <param name="mId">The id of the media to edit</param>
        /// <returns>True if successfully edited</returns>
        bool EditMedia(Media movie, int mId);

        /// <summary>
        /// Delete a specific media
        /// </summary>
        /// <param name="mId">The id of the media to delete</param>
        /// <returns>True if successfully deleted</returns>
        bool DeleteMedia(int mId);

        /// <summary>
        /// Get a list of medias matching the search parameters
        /// </summary>
        /// <param name="condition">The media search parameters</param>
        /// <returns>A list of media objects</returns>
        List<Media> OverviewMedia(MediaSearchParameter condition);

        /// <summary>
        /// Check if a specific media already exists
        /// </summary>
        /// <param name="media">The media object to check for</param>
        /// <returns>True if the media already exists</returns>
        bool MediaExists(Media media);

        /// <summary>
        /// Add a genre to a specific media
        /// </summary>
        /// <param name="gId">The id of the genre to add</param>
        /// <param name="mId">The id of the media</param>
        /// <returns>True if successfully added the genre</returns>
        bool AddGenreToMedia(int gId, int mId);

        /// <summary>
        /// Delete a genre from a specific media
        /// </summary>
        /// <param name="mId">The id of the media</param>
        /// <param name="gId">The id of the genre to delete</param>
        /// <returns>True if successfully deleted the genre from the media</returns>
        bool DeleteGenreFromMedia(int mId, int gId);

        /// <summary>
        /// Get a list of the genres attached to a specific media
        /// </summary>
        /// <param name="mId">The id of the media</param>
        /// <returns>A list of the genres attached to the media</returns>
        List<Genre> OverviewMediaGenre(int mId);

        //Genre methods

        /// <summary>
        /// Create a genre
        /// </summary>
        /// <param name="genre">The genre object to create</param>
        /// <returns>True if successfully created the genre</returns>
        int CreateGenre(Genre genre);

        /// <summary>
        /// Read a specific genre
        /// </summary>
        /// <param name="gId">The id of the genre</param>
        /// <returns>A genre object</returns>
        Genre ReadGenre(int gId);

        /// <summary>
        /// Read a specific genre
        /// </summary>
        /// <param name="name">The name of the genre</param>
        /// <returns>A genre object</returns>
        Genre ReadGenre(string name);

        /// <summary>
        /// Edit a specific genre
        /// </summary>
        /// <param name="genre">The edited genre object</param>
        /// <param name="gId">The id of the genre to edit</param>
        /// <returns>True if successfully edited</returns>
        bool EditGenre(Genre genre, int gId);

        /// <summary>
        /// Delete a specific genre
        /// </summary>
        /// <param name="gId">The id of the genre to delete</param>
        /// <returns>True if succefully deleted the genre</returns>
        bool DeleteGenre(int gId);

        /// <summary>
        /// Get a list of all genres
        /// </summary>
        /// <returns>A list of all genres in the database</returns>
        List<Genre> OverviewGenre();

        /// <summary>
        /// Get a list of all languages
        /// </summary>
        /// <returns>A list of all languages</returns>
        List<Language> OverviewLanguage();

        /// <summary>
        /// Create a comment
        /// </summary>
        /// <param name="comment">The comment object to create</param>
        /// <returns>The id of the comment</returns>
        int CreateComment(Comment comment);

        /// <summary>
        /// Get a specific comment
        /// </summary>
        /// <param name="cId">The id of the comment</param>
        /// <returns>A comment object</returns>
        Comment ReadComment(int cId);

        /// <summary>
        /// Edit a specific comment
        /// </summary>
        /// <param name="comment">The edited comment object</param>
        /// <param name="cId">The id of the comment to edit</param>
        /// <returns>True if successfully edited</returns>
        bool EditComment(Comment comment, int cId);

        /// <summary>
        /// Delete a specific comment
        /// </summary>
        /// <param name="cId">The id of the comment to delete</param>
        /// <returns>True if successfully deleted the comment</returns>
        bool DeleteComment(int cId);

        /// <summary>
        /// Get a list of comments attached to a media
        /// </summary>
        /// <param name="mId">The id of media</param>
        /// <returns>A list of comments</returns>
        List<Comment> GetComments(int mId);

        //Statistic methods

        /// <summary>
        /// Get the 10 most purchased media
        /// </summary>
        /// <returns>A list of the 10 most purchased media</returns>
        List<Media> Top10Purchases();

        /// <summary>
        /// Get the 10 users who have rented/purchased the most
        /// </summary>
        /// <returns>A list of user objects</returns>
        List<User> Top10Renters();

        /// <summary>
        /// Get the 10 best rated movies
        /// </summary>
        /// <returns>A list of movie objects</returns>
        List<Movie> TopRatedMovies(int page, int count = 10);

        /// <summary>
        /// Get the 10 best rated ebooks
        /// </summary>
        /// <returns>A list of ebook objects</returns>
        List<Ebook> Top10RatingEbook();

        /// <summary>
        /// Get the 10 newest media items
        /// </summary>
        /// <returns>A list of media objects</returns>
        List<Media> Top10Newest();

        /// <summary>
        /// Get the 10 users who have made the most comments
        /// </summary>
        /// <returns>A list of comment objects</returns>
        List<User> Top10Commenters();
    }

    public struct MediaSearchParameter
    {
        public string Title { get; set; }

        public string ImdbId { get; set; }

        public string Genre { get; set; }

        public int YearFrom { get; set; }

        public int YearTo { get; set; }

        public string Description { get; set; }

        public int? Page { get; set; }

        public int? Count { get; set; }
    }

    public struct UserSearchParameter
    {
        public string Email { get; set; }

        public string Name { get; set; }

        public int? Page { get; set; }

        public int? Count { get; set; }
    }
}